<?php
/*

  Copyright (c) 2008   by  maxim.oransky <maxim.oransky@gmail.com>,
  auhtor of  the-wheel-library  team

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

class SocketConnect {

	private $fp;
	private $sContentToSend;
	private $isDirty;

	public function __construct($host, $port, $timeoutSeconds) {

		$this->fp = fsockopen($host, $port, $errno, $errstr, $timeoutSeconds);

		if (!$this->fp)
			throw new Exception("Sockopen error ($errno): $errno");

		stream_set_timeout($this->fp, $timeoutSeconds);

		$this->sContentToSend = '';
		$this->isDirty = false;
	}

	private function checkIsNotDirty() {
		if ($this->isDirty)
			throw new Exception(class_name() . ' is dirty. Create new, please');
	}

	public function addSeparator() {
		$this->checkIsNotDirty();
		$this->sContentToSend .= "\r\n";
	}

	public function addLine($str) {
		$this->checkIsNotDirty();
		$this->sContentToSend .= $str . "\r\n";
	}

	/**
	 * @return HttpResponse
	 */
	public function send() {

		$this->checkIsNotDirty();

		$this->sContentToSend = trim($this->sContentToSend);
	    fwrite($this->fp, $this->sContentToSend);

//	    var_dump($this->sContentToSend);

	    $sResponse = '';
	    while (!feof($this->fp)) {
	        $sResponse .= fgets($this->fp, 128);
	    }

	    $this->isDirty = true;

	    return new HttpResponse($sResponse);
	}

	public static function composeData(array $hData) {

		$arrPairs = array();

		foreach ($hData as $key => $value) {

			if (is_object($value) || is_array($value))
				throw new Exception('Field must be string or number');

			$arrPairs[] = self::escapeString($key) . '=' . SocketConnect::escapeString($value);
		}

		return implode('&', $arrPairs);
	}

	/**
	 * Leave all values from a-z, A-Z, and 0-9 alone. These are fine.
     * Convert spaces to a + (plus) sign.
     * Convert everything else to %hh where hh is the hex representation
     * of the character's ASCII value.
	*/
	private static function escapeString($str) {

		$strlen = strlen($str);
		$result = '';

		for ($i = 0; $i < $strlen; $i++) {

			$sym = $str[$i];

			if (preg_match('~[a-zA-Z0-9]~',$sym)) {
				$result .= $sym;
			} else if ($sym == ' ') {
				$result .= '+';
			} else {
				$hex = dechex(ord($sym));
				if (strlen($hex) == 1) $hex = '0' . $hex;
				$result .= '%' . $hex;
			}
		}

		return $result;
	}
}

?>
